// 计算函数
class MatrixCalculator {
    constructor() {
        this.today = new Date();
    }

    // 主算法函数
    calculate(dateParam, luckyNumbers = "", weekday = "周二", shouldReorder = true) {
        // 步骤1: 处理日期参数并生成三个时间戳
        const timestamps = this.generateTimestamps(dateParam);

        // 步骤2: 将时间戳转换为矩阵并进行变换
        const [matrixA, matrixB, matrixC] = this.timestampsToMatrices(timestamps);

        // 步骤3: 处理幸运数字参数
        const processedLuckyNumbers = this.processLuckyNumbers(luckyNumbers, shouldReorder);

        // 步骤4: 矩阵运算
        const C = this.matrixAdd(matrixA, matrixB);
        const D = this.matrixSubtract(matrixB, C);
        const E = this.matrixMultiply(matrixB, matrixA);
        const F = this.matrixDivide(C, matrixA);

        // 步骤5: 创建混合矩阵G
        const G = this.createMixedMatrix();

        // 步骤6: 计算T = C + D - E * F / G
        const temp1 = this.matrixMultiply(E, F);
        const temp2 = this.matrixDivide(temp1, G);
        const temp3 = this.matrixAdd(C, D);
        const T = this.matrixSubtract(temp3, temp2);

        // 步骤7: 转换为00-99范围的数组
        const result = this.matrixToRange(T);

        return {
            timestamps,
            matrices: { A: matrixA, B: matrixB, C: matrixC },
            calculations: { C, D, E, F, G, T },
            finalResult: result,
            luckyNumbers: processedLuckyNumbers,
            weekday
        };
    }

    // 生成三个时间戳：当前日期、往后顺延、往前
    generateTimestamps(dateParam) {
        let targetDate;

        if (typeof dateParam === 'string' && dateParam.length === 8) {
            // 格式如20250101
            const year = parseInt(dateParam.substring(0, 4));
            const month = parseInt(dateParam.substring(4, 6)) - 1; // 月份从0开始
            const day = parseInt(dateParam.substring(6, 8));
            targetDate = new Date(year, month, day);
        } else if (dateParam === 1 || dateParam === "1") {
            // 如果是1，使用今年今月今日
            targetDate = new Date(this.today.getFullYear(), this.today.getMonth(), this.today.getDate());
        } else {
            targetDate = new Date();
        }

        const currentTimestamp = targetDate.getTime();

        // 往后顺延day天
        const day = targetDate.getDate();
        const futureDate = new Date(targetDate);
        futureDate.setDate(futureDate.getDate() + day);
        if (futureDate.getMonth() !== targetDate.getMonth()) {
            futureDate.setMonth(futureDate.getMonth());
        }
        const futureTimestamp = futureDate.getTime();

        // 往前day天
        const pastDate = new Date(targetDate);
        pastDate.setDate(pastDate.getDate() - day);
        const pastTimestamp = pastDate.getTime();

        return [currentTimestamp, futureTimestamp, pastTimestamp];
    }

    // 将时间戳转换为2x5矩阵并进行变换
    timestampsToMatrices(timestamps) {
        return timestamps.map(timestamp => this.timestampToMatrix(timestamp));
    }

    timestampToMatrix(timestamp) {
        // 将时间戳转为字符串，取10位数字
        const timestampStr = Math.abs(timestamp).toString().padStart(10, '0').substring(0, 10);

        // 创建2x5矩阵
        let matrix = [
            [parseInt(timestampStr[0]), parseInt(timestampStr[1]), parseInt(timestampStr[2]), parseInt(timestampStr[3]), parseInt(timestampStr[4])],
            [parseInt(timestampStr[5]), parseInt(timestampStr[6]), parseInt(timestampStr[7]), parseInt(timestampStr[8]), parseInt(timestampStr[9])]
        ];

        // 转置得到5x2矩阵
        matrix = this.transpose(matrix);

        // 按中心行进行镜像 (对5x2矩阵，中心行是索引2)
        matrix = this.mirrorAroundCenter(matrix);

        // 对0,1行和3,4行分别转置
        const rows01 = [matrix[0], matrix[1]];
        const rows34 = [matrix[3], matrix[4]];

        const transposed01 = this.transpose(rows01);
        const transposed34 = this.transpose(rows34);

        // 重新组合矩阵
        return [
            transposed01[0], transposed01[1], matrix[2], transposed34[0], transposed34[1]
        ];
    }

    // 矩阵转置
    transpose(matrix) {
        const rows = matrix.length;
        const cols = matrix[0].length;
        const result = [];

        for (let j = 0; j < cols; j++) {
            result[j] = [];
            for (let i = 0; i < rows; i++) {
                result[j][i] = matrix[i][j];
            }
        }
        return result;
    }

    // 按中心行镜像
    mirrorAroundCenter(matrix) {
        const centerIndex = Math.floor(matrix.length / 2);
        const result = [...matrix];

        for (let i = 0; i < centerIndex; i++) {
            const mirrorIndex = matrix.length - 1 - i;
            [result[i], result[mirrorIndex]] = [result[mirrorIndex], result[i]];
        }

        return result;
    }

    // 处理幸运数字
    processLuckyNumbers(luckyNumbers, shouldReorder) {
        if (!luckyNumbers) return [];

        const numbers = luckyNumbers.split(',')
            .map(num => parseInt(num.trim()))
            .filter(num => !isNaN(num) && num >= 0 && num <= 99);

        if (shouldReorder) {
            return numbers.sort((a, b) => a - b);
        }

        return numbers;
    }

    // 矩阵加法
    matrixAdd(A, B) {
        const result = [];
        for (let i = 0; i < A.length; i++) {
            result[i] = [];
            for (let j = 0; j < A[i].length; j++) {
                result[i][j] = A[i][j] + B[i][j];
            }
        }
        return result;
    }

    // 矩阵减法
    matrixSubtract(A, B) {
        const result = [];
        for (let i = 0; i < A.length; i++) {
            result[i] = [];
            for (let j = 0; j < A[i].length; j++) {
                result[i][j] = A[i][j] - B[i][j];
            }
        }
        return result;
    }

    // 矩阵乘法（元素对应相乘）
    matrixMultiply(A, B) {
        const result = [];
        for (let i = 0; i < A.length; i++) {
            result[i] = [];
            for (let j = 0; j < A[i].length; j++) {
                result[i][j] = A[i][j] * B[i][j];
            }
        }
        return result;
    }

    // 矩阵除法（元素对应相除）
    matrixDivide(A, B) {
        const result = [];
        for (let i = 0; i < A.length; i++) {
            result[i] = [];
            for (let j = 0; j < A[i].length; j++) {
                result[i][j] = B[i][j] !== 0 ? A[i][j] / B[i][j] : 0;
            }
        }
        return result;
    }

    // 创建混合矩阵G（一半0，一半1）
    createMixedMatrix() {
        return [
            [0, 1, 0, 1, 0],
            [1, 0, 1, 0, 1],
            [0, 1, 0, 1, 0],
            [1, 0, 1, 0, 1],
            [0, 1, 0, 1, 0]
        ];
    }

    // 将矩阵转换为01-33范围的数组（适配双色球红球）
     matrixToRange(matrix) {
         const flatArray = matrix.flat();
         const result = [];
         let lowNumberCount = 0; // 统计1-10数字的出现次数
         const maxLowNumbers = 2; // 最多允许2个1-10的数字

         for (let value of flatArray) {
             // 使用更复杂的算法来增加数字分布的均匀性
             let normalizedValue;
             
             // 对原始值进行多重变换以增加随机性
             const transformedValue = Math.abs(value * 7 + 13) * Math.abs(value + 23);
             
             // 使用不同的模数和偏移来避免小数字聚集
             if (transformedValue % 3 === 0) {
                 // 33%概率生成中高数字 (20-33)
                 normalizedValue = (transformedValue % 14) + 20;
             } else if (transformedValue % 5 === 0) {
                 // 20%概率生成中等数字 (11-25)
                 normalizedValue = (transformedValue % 15) + 11;
             } else {
                 // 其他情况生成全范围数字，但对1-10进行限制
                 normalizedValue = (transformedValue % 33) + 1;
                 
                 // 如果是1-10的数字且已达到限制，重新生成
                 if (normalizedValue <= 10 && lowNumberCount >= maxLowNumbers) {
                     normalizedValue = ((transformedValue * 3) % 23) + 11; // 强制生成11-33
                 }
             }
             
             // 确保在1-33范围内
             normalizedValue = Math.max(1, Math.min(33, normalizedValue));
             
             // 统计1-10数字的使用
             if (normalizedValue <= 10) {
                 lowNumberCount++;
             }
             
             result.push(normalizedValue.toString().padStart(2, '0'));
         }

         // 去除重复元素并排序
         const uniqueResult = [...new Set(result)].sort((a, b) => a - b);
         
         // 最终检查：如果1-10数字仍然过多，进行调整
         const finalLowCount = uniqueResult.filter(num => parseInt(num) <= 10).length;
         if (finalLowCount > maxLowNumbers) {
             const adjustedResult = [];
             let currentLowCount = 0;
             
             for (let num of uniqueResult) {
                 const numValue = parseInt(num);
                 if (numValue <= 10) {
                     if (currentLowCount < maxLowNumbers) {
                         adjustedResult.push(num);
                         currentLowCount++;
                     }
                     // 跳过多余的1-10数字
                 } else {
                     adjustedResult.push(num);
                 }
             }
             return adjustedResult;
         }
         
         return uniqueResult;
     }

     // 将矩阵值转换为01-33范围（适配双色球红球）
     transformToRange(matrix) {
         return matrix.map(row => 
             row.map(val => {
                 // 确保值为正数
                 let num = Math.abs(val);
                 
                 // 转换为01-33范围
                 let result = (num % 33) + 1;
                 
                 // 控制低数字(1-10)的分布，减少它们的出现频率
                 if (result <= 10 && Math.random() > 0.3) {
                     result = ((num * 7) % 23) + 11; // 映射到11-33
                 }
                 
                 return result;
             })
         );
     }

    // 双色球专用算法：红球1-33，蓝球1-16
    generateDoubleBall(dateParam, luckyNumbers = "", weekday = "周二") {
        // 使用基础算法获取原始数据
        const baseResult = this.calculate(dateParam, luckyNumbers, weekday, true);
        const baseNumbers = baseResult.finalResult.map(num => parseInt(num));
        
        // 生成红球（6个，范围1-33）
        const redBalls = [];
        const redCandidates = [];
        
        // 从基础结果中筛选1-33的数字作为红球候选
        for (let num of baseNumbers) {
            if (num >= 1 && num <= 33) {
                redCandidates.push(num);
            }
        }
        
        // 只从计算结果中选择红球，不生成额外数字
        // 如果计算结果中的1-33数字不够6个，则选择所有可用的
        const shuffledRed = [...redCandidates].sort(() => Math.random() - 0.5);
        for (let i = 0; i < Math.min(6, shuffledRed.length); i++) {
            if (!redBalls.includes(shuffledRed[i])) {
                redBalls.push(shuffledRed[i]);
            }
        }
        
        // 如果计算结果中的红球候选少于6个，发出警告但不强制补足
        if (redBalls.length < 6) {
            console.warn(`计算结果中只有${redBalls.length}个红球范围(1-33)的数字，无法选择6个红球`);
        }
        
        // 红球排序
        redBalls.sort((a, b) => a - b);
        
        // 生成蓝球（1个，范围1-16）
        let blueBall;
        const blueCandidates = [];
        
        // 从基础结果中筛选1-16的数字作为蓝球候选
        for (let num of baseNumbers) {
            if (num >= 1 && num <= 16) {
                blueCandidates.push(num);
            }
        }
        
        if (blueCandidates.length > 0) {
            // 从候选中随机选择
            const randomIndex = (baseNumbers.reduce((a, b) => a + b, 0) + redBalls.reduce((a, b) => a + b, 0)) % blueCandidates.length;
            blueBall = blueCandidates[randomIndex];
        } else {
            // 如果没有候选，生成一个
            const seed = redBalls.reduce((a, b) => a + b, 0) + baseNumbers.length;
            blueBall = ((seed * 19 + 11) % 16) + 1;
        }
        
        return {
            redBalls: redBalls,
            blueBall: blueBall,
            baseResult: baseResult,
            analysis: {
                redRange: "1-33",
                blueRange: "1-16",
                redCount: 6,
                blueCount: 1,
                generationMethod: "基于矩阵算法的双色球专用生成"
            }
        };
    }

    // 智能双色球选号（结合幸运数字）
    smartDoubleBall(dateParam, luckyNumbers = "", weekday = "周二") {
        const luckyNums = luckyNumbers ? 
            luckyNumbers.split(',').map(num => parseInt(num.trim())).filter(num => !isNaN(num)) : [];
        
        // 获取基础双色球结果
        const baseResult = this.generateDoubleBall(dateParam, luckyNumbers, weekday);
        
        let finalRedBalls = [...baseResult.redBalls];
        let finalBlueBall = baseResult.blueBall;
        
        // 如果有幸运数字，优先处理蓝球
        if (luckyNums.length > 0) {
            // 分离幸运数字：优先将1-16的数字用作蓝球
            const luckyBlueNumbers = [];
            const luckyRedNumbers = [];
            
            luckyNums.forEach(num => {
                if (num >= 1 && num <= 16) {
                    luckyBlueNumbers.push(num);
                } else if (num >= 17 && num <= 33) {
                    luckyRedNumbers.push(num);
                } else if (num >= 34 && num <= 99) {
                    // 大于33的数字映射到红球范围
                    luckyRedNumbers.push(((num - 34) % 33) + 1);
                } else {
                    // 其他数字也映射到红球范围
                    luckyRedNumbers.push((Math.abs(num) % 33) + 1);
                }
            });
            
            // 优先选择幸运数字作为蓝球
            if (luckyBlueNumbers.length > 0) {
                // 如果有多个1-16的幸运数字，随机选择一个
                const randomIndex = (finalRedBalls.reduce((a, b) => a + b, 0)) % luckyBlueNumbers.length;
                finalBlueBall = luckyBlueNumbers[randomIndex];
            }
            
            // 处理红球：合并幸运数字和生成的红球，但要排除已选为蓝球的号码
            if (luckyRedNumbers.length > 0) {
                const combinedRed = [...new Set([...finalRedBalls, ...luckyRedNumbers])]
                    .filter(n => n >= 1 && n <= 33 && n !== finalBlueBall) // 排除蓝球号码
                    .slice(0, 6)
                    .sort((a, b) => a - b);
                
                // 如果红球数量不足6个，从生成结果中补充（排除蓝球）
                if (combinedRed.length < 6) {
                    for (let ball of finalRedBalls) {
                        if (!combinedRed.includes(ball) && ball !== finalBlueBall && combinedRed.length < 6) {
                            combinedRed.push(ball);
                        }
                    }
                    
                    // 如果仍然不够，生成额外的红球（排除蓝球）
                    for (let i = 1; i <= 33 && combinedRed.length < 6; i++) {
                        if (!combinedRed.includes(i) && i !== finalBlueBall) {
                            combinedRed.push(i);
                        }
                    }
                }
                
                finalRedBalls = combinedRed.sort((a, b) => a - b);
            } else {
                // 即使没有幸运红球号码，也要确保红球中不包含蓝球号码
                finalRedBalls = finalRedBalls.filter(ball => ball !== finalBlueBall);
                
                // 如果过滤后红球不足6个，补充新的红球
                if (finalRedBalls.length < 6) {
                    for (let i = 1; i <= 33 && finalRedBalls.length < 6; i++) {
                        if (!finalRedBalls.includes(i) && i !== finalBlueBall) {
                            finalRedBalls.push(i);
                        }
                    }
                    finalRedBalls.sort((a, b) => a - b);
                }
            }
        }
        
        return {
            redBalls: finalRedBalls,
            blueBall: finalBlueBall,
            baseResult: baseResult.baseResult,
            luckyNumbers: luckyNums,
            analysis: {
                ...baseResult.analysis,
                luckyIntegration: luckyNums.length > 0 ? "已融入幸运数字，优先将1-16数字用作蓝球" : "未使用幸运数字",
                recommendation: "建议结合个人喜好数字进行微调"
            }
        };
    }
}

// 使用示例
const calculator = new MatrixCalculator();

// 示例调用
const result1 = calculator.calculate("20250101", "12,45,67,89", "周二", true);
console.log("结果1:", result1.finalResult);

const result2 = calculator.calculate(1, "", "周四", false);
console.log("结果2:", result2.finalResult);

// 导出MatrixCalculator类
export default MatrixCalculator;